package com.zhengaz.common.es.config;

import com.zhengaz.common.es.properties.EsProperties;
import org.apache.http.HttpHost;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.Node;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Objects;

/**
 * @author zhengzg
 * @create 2023-09-14 16:57
 */
@Configuration
public class EsConfig {

    private static final int ADDRESS_LENGTH = 2;

    @Bean
    public EsProperties esProperties() {
        return new EsProperties();
    }

    @Bean
    public RestClientBuilder restClientBuilder(EsProperties esProperties) {
        System.out.println(esProperties);
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();

       // credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));

        HttpHost[] hosts = esProperties.getClusterNodes().stream()
                .map(str -> makeHttpHost(str, esProperties().getScheme()))
                .filter(Objects::nonNull)
                .toArray(HttpHost[]::new);
        RestClientBuilder restClientBuilder = RestClient.builder(hosts);
        // 设置一个监听器，每次节点出现故障时都会收到通知，以防需要采取措施，
        // 当启用故障嗅探时在内部使用。
        restClientBuilder.setFailureListener(new RestClient.FailureListener() {
            @Override
            public void onFailure(Node node) {

            }
        });
        // 设置允许修改默认请求配置的回调
        //（例如请求超时，身份验证或org.apache.http.client.config.RequestConfig.Builder允许设置的任何内容）。
        restClientBuilder.setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
            @Override
            public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder requestConfigBuilder) {
                return requestConfigBuilder
                        .setConnectionRequestTimeout(esProperties.getConnectionRequestTimeout())
                        .setSocketTimeout(esProperties.getSocketTimeout())
                        .setConnectTimeout(esProperties.getConnectTimeout());
            }
        }).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
            @Override
            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {
                return httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
            }
        });
        return restClientBuilder;
    }

    @Bean(name = "highLevelClient")
    public RestHighLevelClient highLevelClient(RestClientBuilder restClientBuilder) {
        // TODO 此处可以进行其它操作
        return new RestHighLevelClient(restClientBuilder);
    }

    /**
     * 根据配置创建HttpHost
     * @param ipStr ip字符串
     * @return http客户端
     */
    private HttpHost makeHttpHost(String ipStr, String scheme) {
        String[] address = ipStr.split(":");
        if (address.length == ADDRESS_LENGTH) {
            String ip = address[0];
            int port = Integer.parseInt(address[1]);
            return new HttpHost(ip, port, scheme);
        } else {
            return null;
        }
    }
}
